package com.pipi.sso.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.pipi.sso.core.service.UserService;
import com.pipi.sso.core.enums.CommonStatusEnum;
import com.pipi.sso.core.enums.DormEnums;
import com.pipi.sso.core.enums.DormErrorCodeEnum;
import com.pipi.sso.core.exception.DormServiceException;
import com.pipi.sso.core.model.UserBO;
import com.pipi.sso.core.util.BeanUtils;
import com.pipi.sso.core.util.DateUtil;
import com.pipi.sso.dao.manager.UserManager;
import com.pipi.sso.dao.model.UserDO;
import com.pipi.sso.dao.query.UserQuery;
import com.pipi.sso.dao.support.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.maihaoche.com
 *
 * @Package com.pipi.sso.core.service.impl
 * @date: 2019/3/21 7:15 PM
 * @Copyright: 2017-2020 www.maihaoche.com Inc. All rights reserved.
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserManager userManager;

    @Override
    public List<UserBO> queryAllUser() {
        UserQuery userQuery = new UserQuery();
        List<UserDO> userDOS = userManager.selectByQuery(userQuery);
        return userDOS.stream().map(userDO -> BeanUtils.createCloneBean(userDO, UserBO.class)).collect(Collectors.toList());
    }

    @Override
    public List<UserBO> queryUser(UserBO userBO) {
        UserQuery userQuery = buildQuery(userBO);
        try {
            List<UserDO> userDOS = userManager.selectByQuery(userQuery);
            return buildBOs(userDOS);
        } catch (Exception e) {
            log.error("查询用户失败！");
            throw new DormServiceException(DormErrorCodeEnum.EXCEPTION);
        }

    }

    @Override
    public void updateUser(UserBO userBO) {
        try {
            // 如果状态不为空，则查询状态
            if (Objects.nonNull(userBO.getStatus())) {
                UserDO userDO = userManager.selectByPrimaryKey(userBO.getUserId());
                if (Objects.isNull(userDO) || userDO.getStatus().equals(userBO.getStatus())) {
                    log.error("{}, userBO is{}, userDO is {}", DormErrorCodeEnum.USER_STATUS_EXCEPTION, JSON.toJSONString(userBO), JSON.toJSONString(userDO));
                    throw new DormServiceException(DormErrorCodeEnum.USER_STATUS_EXCEPTION);
                }

            }
            UserQuery userQuery = new UserQuery();
            UserQuery.Criteria criteria = userQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
            if (Objects.nonNull(userBO.getUserId())) {
                criteria.andUserIdEqualTo(userBO.getUserId());
            }
            if (StringUtils.isNotBlank(userBO.getUsername())) {
                criteria.andUsernameEqualTo(userBO.getUsername());
            }
            UserDO userdo = BeanUtils.createCloneBean(userBO, UserDO.class);
            userManager.updateByQuerySelective(userdo, userQuery);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新用户失败", e);
            throw new DormServiceException(DormErrorCodeEnum.EXCEPTION.getErrCode(), "更新用户失败");
        }
    }

    @Override
    public UserBO queryByUserName(String username) {
        UserQuery userQuery = new UserQuery();
        userQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode())
                .andUsernameEqualTo(username);
        try {
            List<UserDO> userDOS = userManager.selectByQuery(userQuery);
            if (CollectionUtils.isEmpty(userDOS)) {
                return null;
            }
            return buildBO(userDOS.get(0));
        } catch (Exception e) {
            log.error("查询用户失败！username is:{}", username, e);
            throw new DormServiceException(DormErrorCodeEnum.EXCEPTION);
        }

    }

    @Override
    public PageResult<UserBO> queryUserByPaged(UserBO userBO) {
        UserQuery userQuery = buildQuery(userBO);
        userQuery.setPageNo(userBO.getPage());
        userQuery.setPageSize(userBO.getLimit());
        try {
            PageResult<UserDO> pageResult = userManager.selectByQueryWithPage(userQuery);
            if (CollectionUtils.isEmpty(pageResult.getResult())) {
                return PageResult.createPageResult();
            }
            List<UserBO> userBOS = buildBOs(pageResult.getResult());
            return PageResult.createPageResult(userBOS, pageResult.getPageInfo());
        } catch (Exception e) {
            log.error("查询用户失败！");
            throw new DormServiceException(DormErrorCodeEnum.EXCEPTION);
        }
    }

    @Override
    public void addUser(UserBO userBO) {
        try {
            // 先查询用户是否已经存在
            UserQuery userQuery = new UserQuery();
            userQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode())
                    .andUsernameEqualTo(userBO.getUsername());
            List<UserDO> userDOS = userManager.selectByQuery(userQuery);
            // 如果存在，则提示
            if (CollectionUtils.isNotEmpty(userDOS)) {
                throw new DormServiceException(DormErrorCodeEnum.USER_IS_EXIST);
            }
            UserDO addUserDO = BeanUtils.createCloneBean(userBO, UserDO.class);
            addUserDO.setStatus(CommonStatusEnum.YES.getCode());
            addUserDO.setIsDeleted(CommonStatusEnum.NO.getCode());
            userManager.insertSelective(addUserDO);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("添加用户失败， userBO is {}", JSON.toJSONString(userBO), e);
            throw new DormServiceException(DormErrorCodeEnum.ADD_USER_FAIL);
        }
    }

    private UserQuery buildQuery(UserBO userBO) {
        UserQuery userQuery = new UserQuery();
        userQuery.setOrderByClause("gmt_create desc");
        UserQuery.Criteria criteria = userQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
        if (Objects.nonNull(userBO)) {
            if (Objects.nonNull(userBO.getUserId())) {
                criteria.andUserIdEqualTo(userBO.getUserId());
            }
            if (StringUtils.isNotBlank(userBO.getUsername())) {
                criteria.andUsernameLike("%" + userBO.getUsername() + "%");
            }
            if (StringUtils.isNotBlank(userBO.getName())) {
                criteria.andNameLike("%" + userBO.getName() + "%");
            }
            if (Objects.nonNull(userBO.getRoleId())) {
                criteria.andRoleIdEqualTo(userBO.getRoleId());
            }
        }
        return userQuery;
    }

    private List<UserBO> buildBOs(List<UserDO> userDOS) {
        return userDOS.stream().map(this::buildBO).collect(Collectors.toList());
    }

    private UserBO buildBO(UserDO userDO) {
        if (Objects.isNull(userDO)) {
            return null;
        }
        UserBO userBO = BeanUtils.createCloneBean(userDO, UserBO.class);
        userBO.setRole(DormEnums.RoleEnum.getRoleById(userDO.getRoleId()));
        userBO.setGmtCreateDesc(DateFormatUtils.format(userBO.getGmtCreate(), DateUtil.PATTERN_2));
        return userBO;
    }

}
